package cn.yangtianxia.user.service.impl;

import cn.yangtianxia.basic.constant.BaseConstants;
import cn.yangtianxia.basic.dto.RegisterDto;
import cn.yangtianxia.basic.exception.BusinessException;
import cn.yangtianxia.basic.service.Impl.BaseServiceImpl;
import cn.yangtianxia.basic.util.MD5Utils;
import cn.yangtianxia.basic.util.StrUtils;
import cn.yangtianxia.user.domain.Logininfo;
import cn.yangtianxia.user.domain.User;
import cn.yangtianxia.user.mapper.UserMapper;
import cn.yangtianxia.user.service.ILogininfoService;
import cn.yangtianxia.user.service.IUserService;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.StringUtils;

/**
 * <p>
 *  服务实现类
 * </p>
 *
 * @author yangtianxia
 * @since 2022-04-01
 */
@Service
public class UserServiceImpl extends BaseServiceImpl<User> implements IUserService {

    @Autowired
    private UserMapper userMapper;

    @Autowired
    private RedisTemplate redisTemplate;

    //职责分离
    @Autowired
    public ILogininfoService logininfoService;

    /**
     * 手机注册
     * @param dto
     */
    @Override
    @Transactional
    public void phoneRegister(RegisterDto dto) {
        String phone = dto.getPhone();
        String smsCode = dto.getSmsCode();//0215
        String confirmPassword = dto.getConfirmPassword();
        String password = dto.getPassword();
        //redis的key
        String smsCodeKey = BaseConstants.VerifyCodeConstants.BUSINESS_REGISTER_PREFIX + phone;
        //空校验
        if (!StringUtils.hasLength(phone)
                || !StringUtils.hasLength(smsCode)
                || !StringUtils.hasLength(confirmPassword)
                || !StringUtils.hasLength(password)
        ){
            throw new BusinessException("注册请填写必要信息");
        }
        //两次密码校验
        if (!password.equals(confirmPassword)){
            throw new BusinessException("两次密码必须一致");
        }
        //手机验证码
        Object smsCodeValue = redisTemplate.opsForValue().get(smsCodeKey);//密码加时间戳
        String smsCodeValueTmp = smsCodeValue.toString().split(":")[0];
        if (smsCodeValueTmp == null){
            throw new BusinessException("验证码已过期请点击重写获取");
        }
        //验证码校验
        if (!smsCodeValueTmp.equalsIgnoreCase(smsCode)){
            throw new BusinessException("请输入正确的手机验证码");
        }
        //添加操作初始化user
        User user = dto2User(dto);
        //拷贝
        Logininfo logininfo = user2user2Logininfo(user);
        logininfoService.save(logininfo);
        user.setLogininfoId(logininfo.getId());//获取自增长id
        userMapper.save(user);
    }

    /**
     * 邮箱注册
     * @param dto
     */
    @Override
    public void emailRegister(RegisterDto dto) {
        String phone = dto.getPhone();
        String email = dto.getEmail();
        String smsCode = dto.getSmsCode();//0215
        String confirmPassword = dto.getConfirmPassword();
        String password = dto.getPassword();
        //redis的key
        String smCodeKey = BaseConstants.VerifyCodeConstants.BUSINESS_REGISTER_PREFIX + email;
        //空校验
        if (!StringUtils.hasLength(email)
                || !StringUtils.hasLength(smsCode)
                || !StringUtils.hasLength(confirmPassword)
                || !StringUtils.hasLength(password)
        ){
            throw new BusinessException("注册请填写必要信息");
        }
        //两次密码校验
        if (!password.equals(confirmPassword)){
            throw new BusinessException("两次密码必须一致");
        }
        //手机验证码
        Object smsCodeValue = redisTemplate.opsForValue().get(smCodeKey);//密码加时间戳
        String smsCodeValueTmp = smsCodeValue.toString().split(":")[0];
        if (smsCodeValueTmp == null){
            throw new BusinessException("验证码已过期请点击重写获取");
        }
        //验证码校验
        if (!smsCodeValueTmp.equalsIgnoreCase(smsCode)){
            throw new BusinessException("请输入正确的邮箱验证码");
        }
        //添加操作初始化user
        User user = dto2User(dto);
        //拷贝
        Logininfo logininfo = user2user2Logininfo(user);
        logininfoService.save(logininfo);
        user.setLogininfoId(logininfo.getId());//获取自增长id
        userMapper.save(user);
    }

    private Logininfo user2user2Logininfo(User user) {
        Logininfo logininfo = new Logininfo();
        BeanUtils.copyProperties(user,logininfo);
        logininfo.setType(1);//认定类型是员工
        return logininfo;
    }

    private User dto2User(RegisterDto dto) {
        User user = new User();
        user.setUsername(dto.getPhone());
        user.setPhone(dto.getPhone());
        user.setEmail(dto.getEmail());
        String salt = StrUtils.getComplexRandomString(32);
        String password = MD5Utils.encrypByMd5(dto.getPassword() + salt);
        user.setSalt(salt);
        user.setPassword(password);
        return user;
    }

    /**
     * 我们在CUD user表的时候，需要级联操作logininfo，所以我们需要复写 save update  remove
     */
    @Override
    @Transactional
    public void save(User user) {
        //拷贝
        Logininfo logininfo = user2user2Logininfo(user);
        logininfoService.save(logininfo);
        user.setLogininfoId(logininfo.getId());//获取自增长id
        userMapper.save(user);
    }

    @Override
    @Transactional
    public void update(User user) {
        //拷贝
        Logininfo logininfo = user2user2Logininfo(user);
        logininfoService.update(logininfo);
        userMapper.update(user);
    }

    @Override
    @Transactional
    public void delete(Long id) {
        User user = userMapper.loadById(id);
        logininfoService.delete(user.getLogininfoId());
        userMapper.delete(id);
    }
}
